import { ref, computed } from 'vue'

interface RequestOptions {
    url: string
    method?: 'GET' | 'POST' | 'PUT' | 'DELETE'
    data?: any
    headers?: Record<string, string>
    timeout?: number
}

interface RequestState<T> {
    data: T | null
    loading: boolean
    error: Error | null
}

// 简单的请求执行
const executeRequest = async (options: RequestOptions): Promise<any> => {
    const { url, method = 'GET', data, headers = {}, timeout = 10000 } = options

    return new Promise((resolve, reject) => {
        uni.request({
            url,
            method: method as any,
            data,
            header: headers,
            timeout,
            success: (res) => {
                if (res.statusCode >= 200 && res.statusCode < 300) {
                    resolve(res.data)
                } else {
                    reject(new Error(`Request failed with status ${res.statusCode}`))
                }
            },
            fail: (err) => {
                reject(new Error(err.errMsg || 'Request failed'))
            }
        })
    })
}

export function useRequest<T = any>() {
    const state = ref<RequestState<T>>({
        data: null,
        loading: false,
        error: null
    })

    const request = async (options: RequestOptions): Promise<T> => {
        state.value.loading = true
        state.value.error = null

        try {
            const result = await executeRequest(options)
            state.value.data = result
            return result
        } catch (error) {
            state.value.error = error as Error
            throw error
        } finally {
            state.value.loading = false
        }
    }

    // GET请求
    const get = (url: string, params?: any) => {
        return request({
            url: params ? `${url}?${new URLSearchParams(params).toString()}` : url,
            method: 'GET'
        })
    }

    // POST请求
    const post = (url: string, data?: any) => {
        return request({
            url,
            method: 'POST',
            data
        })
    }

    return {
        loading: computed(() => state.value.loading),
        error: computed(() => state.value.error),
        data: computed(() => state.value.data),
        request,
        get,
        post
    }
}

// 批量请求hook
export function useBatchRequest() {
    const requests = ref<Array<{ key: string; promise: Promise<any>; status: 'pending' | 'fulfilled' | 'rejected' }>>([])

    const addRequest = (key: string, requestFn: () => Promise<any>) => {
        const promise = requestFn()
        requests.value.push({
            key,
            promise,
            status: 'pending'
        })

        promise
            .then(() => {
                const request = requests.value.find((r) => r.key === key)
                if (request) request.status = 'fulfilled'
            })
            .catch(() => {
                const request = requests.value.find((r) => r.key === key)
                if (request) request.status = 'rejected'
            })

        return promise
    }

    const executeAll = async (concurrency = 5) => {
        const results: Record<string, any> = {}
        const errors: Record<string, Error> = {}

        // 分批执行
        for (let i = 0; i < requests.value.length; i += concurrency) {
            const batch = requests.value.slice(i, i + concurrency)
            const batchResults = await Promise.allSettled(batch.map((r) => r.promise))

            batchResults.forEach((result, index) => {
                const request = batch[index]
                if (result.status === 'fulfilled') {
                    results[request.key] = result.value
                } else {
                    errors[request.key] = result.reason
                }
            })
        }

        return { results, errors }
    }

    const clear = () => {
        requests.value = []
    }

    return {
        requests: computed(() => requests.value),
        addRequest,
        executeAll,
        clear
    }
}
